package com.ruoyi.system.service.impl;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.jushuitan.api.ApiClient;
import com.jushuitan.api.ApiRequest;
import com.jushuitan.api.ApiResponse;
import com.jushuitan.api.DefaultApiClient;
import com.ruoyi.common.config.JuShuiTanConfig;
import com.ruoyi.common.config.WxConfig;
import com.ruoyi.common.config.WxPayConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SignUtil;
import com.ruoyi.system.domain.*;

import com.ruoyi.system.domain.dto.BdmOrdersUploadDataDto;
import com.ruoyi.system.domain.dto.BdmOrdersUploadDto;

import com.ruoyi.system.domain.vo.BdmOrderVo;
import com.ruoyi.system.domain.vo.BdmTeamAdminVo;
import com.ruoyi.system.enums.BdmMemberRuleEnum;
import com.ruoyi.system.enums.BdmOrderEnum;
import com.ruoyi.system.enums.BdmRoyaltyRecordEnum;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.domain.vo.BdmMemberRuleVo;
import com.ruoyi.system.domain.vo.BdmUserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 分销逻辑实现类
 */
@Slf4j
@Service
public class IDistributionServiceImpl implements IDistributionService {

    /**
     * 字符编码
     **/
    private static final String charset = "UTF-8";
    /**
     * 客户编码
     **/
    private static final String EBusinessID = "1834513";
    /**
     * 客户秘钥
     **/
    private static final String appKey = "246e5145-6545-4cbe-bb08-adb9d15f2f1b";
    /**
     * 接口请求地址
     **/
    private static final String sandRequestUrl = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";

    @Autowired
    private BdmGoodMapper bdmGoodMapper;

    @Autowired
    private BdmUserMapper bdmUserMapper;

    @Autowired
    private BdmRoyaltyRecordMapper bdmRoyaltyRecordMapper;

    @Autowired
    private BdmMemberRuleMapper bdmMemberRuleMapper;

    @Autowired
    private BdmMemberLevelMapper bdmMemberLevelMapper;

    @Autowired
    private IBdmShareOutBonusLevelService iBdmShareOutBonusLevelService;

    @Autowired
    private IBdmShareOutBonusLevelRecordService iBdmShareOutBonusLevelRecordService;

    @Autowired
    private IBdmBalanceChangeService iBdmBalanceChangeService;

    @Autowired
    private JuShuiTanConfig juShuiTanConfig;

    @Autowired
    private IBdmOrderService iBdmOrderService;

    @Autowired
    private IBdmOrderShipmentsService bdmOrderShipmentsService;

    @Autowired
    private IBdmUserService iBdmUserService;

    @Autowired
    private BdmShareOutBonusLevelMapper bdmShareOutBonusLevelMapper;

    @Value("${pay.terminalCode}")
    private String terminalCode;

    @Value("${pay.password}")
    private String password;

    /**
     * 购买vip礼包
     * 扫推荐人码的时候绑定分销奖励上级关系,不能同时绑定上级跟上级分销关系,同时绑定这里会把下级的普通用户会设置成上上级
     *
     * @param userId 购买者userId
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public synchronized void vipAward(Long userId, String orderId, Long productId) {
        // 查询当前用户信息
        BdmUserVo bdmUserVo = this.getBdmUser(userId);
        // 用户信息保存到用户会员表
        saveBdmMemberRule(userId, BdmMemberRuleEnum.VIP.getLevel(), productId);
        // 单单奖
        BdmGood bdmGood = bdmGoodMapper.selectbdmGoodById(productId);
        // 单单奖
        List<BdmUserVo> voList = new ArrayList<>();
        getUpUser(voList,userId);
        voList.remove(bdmUserVo);
        //一个人在推荐关系上，可能有多个总裁等等；取最近关系的即可，一个等级只能给一次，且等级只能是比直属上级高的
        int[] arr={0,0,0,0};
        // 直属上级的
        BdmMemberRule directBdmMemberRule =new  BdmMemberRule();
        if(voList.size()>0){
             directBdmMemberRule = bdmMemberRuleMapper.selectOne(Wrappers.<BdmMemberRule>lambdaQuery().eq(BdmMemberRule::getSysUserid, voList.get(0).getSysUserid()));
        }

        Long  melemberAgencyLevel=0l;
        for (BdmUserVo userVo : voList) {
            Long sysUserid = userVo.getSysUserid();
            BdmMemberRule bdmMemberRule = bdmMemberRuleMapper.selectOne(Wrappers.<BdmMemberRule>lambdaQuery().eq(BdmMemberRule::getSysUserid, sysUserid));
            //防止空指针异常
                try{
                    if(ObjectUtils.isEmpty(directBdmMemberRule.getMemberAgencyLevel())){
                        melemberAgencyLevel= BdmMemberRuleEnum.SVIP.getLevel();
                        directBdmMemberRule.setMemberAgencyLevel(0l);
                    }
                }catch (Exception e){
                    continue;
                }//////////////////
            if (bdmMemberRule !=null && bdmMemberRule.getMemberAgencyLevel() != null
                    && bdmMemberRule.getMemberAgencyLevel()> BdmMemberRuleEnum.SVIP.getLevel()
                    && bdmMemberRule.getMemberAgencyLevel()> melemberAgencyLevel
                    ){
                BigDecimal bigDecimal =  BigDecimal.ZERO;
                switch (bdmMemberRule.getMemberAgencyLevel().toString()){
                    case "3":
                        if(arr[0]==1){
                            continue;
                        }
                        arr[0]=1;
                        melemberAgencyLevel=3l;
                        bigDecimal = bdmGood.getSharedShareBonus();
                        break;
                    case "4":
                        if(arr[1]==1){
                            continue;
                        }
                        arr[1]=1;
                        melemberAgencyLevel=4l;
                        bigDecimal = bdmGood.getJointProductionBonus();
                        break;
                    case "5":
                        if(arr[2]==1){
                            continue;
                        }
                        arr[2]=1;
                        melemberAgencyLevel=5l;
                        bigDecimal = bdmGood.getRegionalOperationBonus();
                        break;
                    case "6":
                        if(arr[3]==1){
                            continue;
                        }
                        arr[3]=1;
                        melemberAgencyLevel=6l;
                        bigDecimal = bdmGood.getPresidentBonus();
                        break;
                    default:
                }
                if(bigDecimal.compareTo( BigDecimal.ZERO)!=0){
                    this.insertBdmRoyaltyRecord(sysUserid, BdmRoyaltyRecordEnum.SINGLE_PRIZE.getType(), bigDecimal, orderId,1);
                    // 修改上级单单奖收益
                    this.updateBdmUser(sysUserid,  bigDecimal,1);
                }
            }
        }

        // 如果当前购买vip的用户上级是空或者是普通用户不计算奖励
//        if (bdmUserVo.getDistributionParentId() == null) {
//            return;
//        }

   //     System.out.println("检测有没推荐上级");
        if (bdmUserVo.getParentId() == null ) {
            return;
        }
     //   System.out.println("检测有没推荐上级完毕");

        // 设置默认位置
        if(bdmUserVo.getLocation()==null || bdmUserVo.getLocation()==0){
            // 加个判断  是否第一次成为vip
            Integer location = bdmUserMapper.selectUserMaxLocation(bdmUserVo.getParentId());
            if(location==null){
                location=0;
            }
            BdmUser bdmUser = new BdmUser();
            bdmUser.setLocation(location+1);
            bdmUser.setSysUserid(userId);
            bdmUserMapper.updateBdmUserBySysUserId(bdmUser);
//            bdmUserMapper.setUserDefaultLocation(userId,bdmUserVo.getParentId());
            bdmUserVo = bdmUserMapper.selectUserByUserId(userId);
        }
        // 上级如果是普通用户没有奖励
        BdmMemberRuleVo memberRuleVo = this.getMemberRule(bdmUserVo.getParentId());
        if (memberRuleVo == null || memberRuleVo.getState() == 2) {
            return;
        }

        BigDecimal decimal = bdmGood.getDirectPremium();
        if(bdmUserVo.getParentId().equals(bdmUserVo.getDistributionParentId())){
            decimal=decimal.add(bdmGood.getRecommendedRoom());
        }
        // 购买者直属上级分销提成记录
        this.insertBdmRoyaltyRecord(bdmUserVo.getParentId(), BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(),decimal, orderId,1);

        // 修改上级直推收益
        this.updateBdmUser(bdmUserVo.getParentId(), decimal,1);

        String bounsValue = bdmGood.getBounsValue();
        if (StringUtils.isNoneBlank(bounsValue)){
            Long sysUserid = bdmUserVo.getParentId();
            List<BdmUser> user = iBdmUserService.lambdaQuery().eq(BdmUser::getParentId, sysUserid).list();
            if (!CollectionUtils.isEmpty(user)){
                for (BdmUser bdmUser : user) {
                    bdmUser.setCreditScore(new BigDecimal(bdmUser.getCreditScore()).add(new BigDecimal(bdmGood.getBounsValue())).toString());
                    iBdmUserService.updateBdmUser(bdmUser);
                }
            }
        }

        // 分销奖励 和
        if(bdmUserVo.getParentId().equals(bdmUserVo.getDistributionParentId())){
          //  System.out.println("直推和平台奖励；给一个人了");
            return;
        }

        BdmUserVo svipUpUser =null;
      //  System.out.println("检测有没有分销关系");
        if (bdmUserVo.getDistributionParentId() == null) {
            // 寻找svip 的上级
          //  System.out.println("开始递归查询---"+bdmUserVo.getParentId());
            List<BdmUserVo>  svipList= new ArrayList<>();
            getSvipUpUser(bdmUserVo.getParentId(),svipList);
            if(svipList.size()==0){
                return;
            }else{
                svipUpUser = svipList.get(0);
             //   System.out.println("开始绑定分销关系");
                // 绑定分销关系
                bdmUserVo.setDistributionParentId(svipUpUser.getSysUserid());
                BdmUser bdmUser = new BdmUser();
                bdmUser.setSysUserid(bdmUserVo.getSysUserid());
                bdmUser.setId(bdmUserVo.getId());
                bdmUser.setDistributionParentId(svipUpUser.getSysUserid());
                bdmUserMapper.updateBdmUser(bdmUser);
            }
        }else{
            svipUpUser =  this.getBdmUser(bdmUserVo.getDistributionParentId());
        }



      //  System.out.println("开始分配分销关系奖励");
        // 上级的上级是svip,计算间接奖
        this.insertBdmRoyaltyRecord(svipUpUser.getSysUserid(), BdmRoyaltyRecordEnum.RECOMMENDED_ROOM.getType(), bdmGood.getRecommendedRoom(), orderId,1);
        // 修改上上级收益
        this.updateBdmUser(svipUpUser.getSysUserid(), bdmGood.getRecommendedRoom(),1);

        /**
        // 查询购买者直属上级的上级
        BdmUserVo bdmUser = this.getBdmUser(bdmUserVo.getDistributionParentId());
        BdmMemberRuleVo upUpUserId = this.getMemberRule(bdmUser.getDistributionParentId());
//        // 计算上级的下属人数,如果人数达到两人,那么自动升级为svip,此时升级后的svip下属归svip升级前的上级,如果上级是vip,那么不进行关联
//        whetherUpgrade(bdmUserVo.getDistributionParentId(), BdmMemberRuleEnum.VIP.getLevel(), 1,userId);
        // vip没有间接奖
        if (upUpUserId == null || upUpUserId.getMemberLevel().equals(BdmMemberRuleEnum.VIP.getLevel())) {
            return;
        }
        // 上级的上级是svip,计算间接奖
        this.insertBdmRoyaltyRecord(upUpUserId.getSysUserid(), BdmRoyaltyRecordEnum.RECOMMENDED_ROOM.getType(), bdmGood.getRecommendedRoom(), orderId,1);
        // 修改上上级收益
        this.updateBdmUser(upUpUserId.getSysUserid(), bdmGood.getRecommendedRoom(),1);
        */
    }

    /**
     * 购买代理礼包
     *
     * @param userId    购买者礼包
     * @param orderId   订单id
     * @param productId 商品id
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void agencyAward(Long userId, String orderId, Long productId) {

        // 查询当前用户信息
        BdmUserVo bdmUserVo = this.getBdmUser(userId);
        // 查询当前购买的商品是什么等级
        BdmGood bdmGood = bdmGoodMapper.selectbdmGoodById(productId);

        // 购买代理商品等级 3共享店主 4联创 5区域运营 6总裁
        Long productLevel = bdmGood.getProductLevel();

        // 用户信息保持到用户会员表
        saveBdmMemberRule(userId, productLevel, productId);

        // 如果当前购买代理的用户上级是空不计算奖励
        if (bdmUserVo.getParentId() == null) {
            return;
        }
        // 查询购买者直属上级 代理礼包走的是推荐人关系
        BdmMemberRuleVo memberRuleVo = this.getMemberRule(bdmUserVo.getParentId());
        // 如果上级不是代理商没有奖励
        if (memberRuleVo == null || memberRuleVo.getMemberAgencyLevel() == null) {
            return;
        }

        // 购买之自身的代理等级
        BdmMemberRuleVo selfMemberRuleVo = this.getMemberRule(bdmUserVo.getSysUserid());
        if (selfMemberRuleVo == null || selfMemberRuleVo.getMemberAgencyLevel() == null) {
            selfMemberRuleVo=new BdmMemberRuleVo();
            selfMemberRuleVo.setMemberAgencyLevel(2l);
        }


        String bounsValue = bdmGood.getBounsValue();
        if (StringUtils.isNoneBlank(bounsValue)){
            Long sysUserid = bdmUserVo.getParentId();
            BdmUser user = iBdmUserService.lambdaQuery().eq(BdmUser::getDistributionParentId, sysUserid).eq(BdmUser::getSysUserid, userId).one();
            if (user != null){
                user.setCreditScore(new BigDecimal(user.getCreditScore()).add(new BigDecimal(bdmGood.getBounsValue())).toString());
                iBdmUserService.updateBdmUser(user);
            }
        }
        // 查询对应代理等级奖励
        List<BdmMemberLevel> levelList = bdmMemberLevelMapper.selectBdmMemberLevelList(null);

        // 上级代理商的等级 3共享店主 4联创 5区域运营 6总裁
        Long memberAgencyLevel = memberRuleVo.getMemberAgencyLevel();
        List<BdmUserVo> voList = new ArrayList<>();
        getUpUser(voList,userId);
        // 团队奖
        voList.remove(bdmUserVo);
        int[] groupAwardArr={0,0,0,0};
        if(ObjectUtils.isEmpty(memberAgencyLevel)){
            memberAgencyLevel=2l;
        }
        for (BdmUserVo vo : voList) {
            groupAward(orderId, levelList, bdmGood, vo,memberAgencyLevel,groupAwardArr,selfMemberRuleVo);
        }
        // 250807 徐小波更改
        extracted1(orderId, memberAgencyLevel, productLevel, levelList, bdmUserVo,bdmGood);
        // 查找上级代理的下属是否有三人跟自己同级,同级上级进行升级
        whetherUpgrade(bdmUserVo.getParentId(), memberAgencyLevel, 2,userId);
    }


    /**
     * 查找对应下属位置销售情况,达标可参与奖金池分红
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void setLocation() {
        BdmShareOutBonusLevel bonusLevel = iBdmShareOutBonusLevelService.lambdaQuery().eq(BdmShareOutBonusLevel::getStatus, 1).one();
        if (bonusLevel == null || bonusLevel.getSinglePerformance().compareTo(BigDecimal.ZERO) < 0) {
            return;
        }
        BigDecimal singlePerformance = bonusLevel.getSinglePerformance();
        // 找出svip等级的用户
        List<Long> svipUserIdList = bdmUserMapper.getSvipUserIdList();
        for (Long userId : svipUserIdList) {
            boolean flag = true;
            // 找出对应svip的下级的1跟2号位  注意:位置只能设置单个不能重复,否则这里会出现判断错误,这里找的是对应推荐关系,不是分销奖励关系
            List<Long> vipUserIdList = bdmUserMapper.getSubordinateVip(userId);
            if (CollectionUtils.isEmpty(vipUserIdList) || vipUserIdList.size() < 2) {
                continue;
            }
            // 找出下级购买商品(推荐关系)
            for (Long vipUserId : vipUserIdList) {
                List<Long> lowerUserIds = bdmUserMapper.getLocationLowerUserId(vipUserId);
                if (!CollectionUtils.isEmpty(lowerUserIds)) {
                    BigDecimal number = bdmUserMapper.getUserMoney(lowerUserIds);
                    if (number == null || number.compareTo(singlePerformance) < 0) {
                        flag = false;
                        break; // 有一个不达标就可以直接退出
                    }
                } else {
                    flag = false; // 没有下级也不达标
                    break;
                }
            }
            // 如果为true,设置当前用户有分红权
            if (flag) {
                bonusLevel.setNumberOfPeople(bonusLevel.getNumberOfPeople() + 1);
                iBdmShareOutBonusLevelService.updateById(bonusLevel);
                bdmUserMapper.updateUserBonusFlag(userId);
            }
        }

    }

    /**
     * 奖金池分红
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void shareOutBonus() {
        BdmShareOutBonusLevel bonusLevel = bdmShareOutBonusLevelMapper.selectByStatus(1);
        if (bonusLevel == null || bonusLevel.getAtPresentMoney().compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        BigDecimal zero = BigDecimal.ZERO;
        // 找出符合分红的用户
        List<Long> userIdList = bdmUserMapper.getShareOutBonusUserId();
        if (!CollectionUtils.isEmpty(userIdList)) {
            // 平均分
            BigDecimal average = bonusLevel.getAtPresentMoney().divide(BigDecimal.valueOf(userIdList.size()), 2, RoundingMode.HALF_UP);
            zero =zero.add(average);
            for (Long userId : userIdList) {
                insertBdmRoyaltyRecord(userId, BdmRoyaltyRecordEnum.DIVIDEND_AWARD.getType(), average, null,1);
                // 修改用户收益
                BdmUserVo bdmUserVo = bdmUserMapper.getBdmUserByUserId(userId);
                // 计算收益信息(收益指的是不可用余额,确认收货后进行解冻)
                BdmUser bdmUser = new BdmUser();
                bdmUser.setSysUserid(bdmUserVo.getSysUserid());
                bdmUser.setId(bdmUserVo.getId());
                bdmUser.setRemainingSum(bdmUserVo.getRemainingSum().add(average));
                bdmUserMapper.updateBdmUser(bdmUser);

                BdmBalanceChange change = new BdmBalanceChange();
                change.setUserId(userId);
                change.setVariation(zero.toString());
                change.setVariationBefore(bdmUserVo.getEarnings().toString());
                change.setVariationAfter(bdmUserVo.getEarnings().add(zero).toString());
                change.setVariationType(3L);
                change.setAddOrSubtract(1L);
                change.setBusinessType(BdmRoyaltyRecordEnum.DIVIDEND_AWARD.getType());
                iBdmBalanceChangeService.insertBdmBalanceChange(change);
            }
        }
        // 发放记录
        BdmShareOutBonusLevelRecord share = new BdmShareOutBonusLevelRecord();
        share.setGrantMoney(bonusLevel.getAtPresentMoney());
        share.setGrantNumber(userIdList.size());
        share.setAvgMoney(zero);
        share.setCreateTime(LocalDateTime.now());
        iBdmShareOutBonusLevelRecordService.save(share);
        // 清空每月分红金额,设置累计金额
        bonusLevel.setAccumulativeTotal(bonusLevel.getAccumulativeTotal().add(bonusLevel.getAtPresentMoney()));
        bonusLevel.setAtPresentMoney(BigDecimal.ZERO);
        bonusLevel.setUpdateTime(LocalDateTime.now());
        iBdmShareOutBonusLevelService.updateById(bonusLevel);
    }


    /**
     * 查找直属上级,如果是vip查看是否符合升级条件
     *
     * @param upUserId 购买者上级用户id
     * @param level    会员等级
     * @param flag     vip 代理商标识
     */
    @Override
    public void whetherUpgrade(Long upUserId, Long level, int flag,Long userId) {
        List<Long> userIdList = bdmUserMapper.selectUpUserId(upUserId);
        // 根据购买者上级id查看直系下属vip的数量是否超过两个,如果超过两个,那么升级成svip
        int number = bdmMemberRuleMapper.getUnderlingNumberBySuperiorId(upUserId, level, flag);

        int upgradeNumber = flag == 1 ? 2 : 3;
        BdmMemberLevel bdmMemberLevel = bdmMemberLevelMapper.selectOne(Wrappers.<BdmMemberLevel>lambdaQuery().eq(BdmMemberLevel::getMemberLevelType, level + 1));
        if (bdmMemberLevel != null && bdmMemberLevel.getUpgradeNumber() != null && bdmMemberLevel.getUpgradeNumber() != 0) {
            upgradeNumber = bdmMemberLevel.getUpgradeNumber();
        }

        BdmMemberRuleVo memberRule = getMemberRule(upUserId);
        if (memberRule != null && !ObjectUtils.isEmpty(memberRule.getMemberLevel()) && !memberRule.getMemberLevel().equals(2L)) {
            if (flag == 1 && number >= upgradeNumber && (level + 1) <= 2) {
                // 购买者上级符合升级条件,升级为svip
                updateBdmMemberRule(upUserId, level + 1);
                int i = 0;
                for (Long id : userIdList) {
                    BdmMemberRuleVo memberRules = getMemberRule(id);
                    if (memberRules.getMemberLevel().equals(2L) && i == 0) {
                        bdmUserMapper.updateUserAwardHierarchy(upUserId, 1);
                        i++;
                    }
                }
                // 升级后购买者上级的下属归购买者的上上级 必须是svip,如果不是必须是一条线上的第一个svip
                iBdmUserService.lambdaUpdate().set(BdmUser::getDistributionParentId,null).eq(BdmUser::getSysUserid,upUserId).update();
                if (i == 0){
                    iBdmUserService.lambdaUpdate().set(BdmUser::getDistributionParentId, null).in(BdmUser::getDistributionParentId, upUserId).update();
                }
            }
        }

        if (flag == 2 && number >= upgradeNumber && (level + 1) <= 6) {
            // 购买者上级符合升级条件,升级为对应代理
            bdmMemberRuleMapper.updateBdmMemberRuleAgency(upUserId, level + 1);
            // 升级后购买者上级的下属归购买者的上上级
//            bdmUserMapper.updateUserAwardHierarchy(upUserId, 2);
//            iBdmUserService.lambdaUpdate().set(BdmUser::getDistributionParentId,null).eq(BdmUser::getSysUserid,userId).update();
        }


    }

    /**
     * 新增分销提成记录
     *
     * @param sysUserId 分成者id
     * @param type      类型 1直推 2间推 3单单奖 4平级推奖 5跨级推奖
     * @param amount    分成金额
     */
    private void insertBdmRoyaltyRecord(Long sysUserId, String type, BigDecimal amount, String orderId,int flag) {
        BdmRoyaltyRecord record = new BdmRoyaltyRecord();
        record.setSysUserid(sysUserId);
        record.setAmount(amount);
        if (StringUtils.isBlank(orderId)) {
            record.setStatus("2");
        }
        record.setOrderId(orderId);
        record.setType(type);
        record.setCreateTime(new Date());
        record.setCreateBy(sysUserId.toString());
        bdmRoyaltyRecordMapper.insertBdmRoyaltyRecord(record);

        BdmUserVo bdmUserVo = bdmUserMapper.getBdmUserByUserId(sysUserId);
        BdmBalanceChange change = new BdmBalanceChange();
        change.setUserId(sysUserId);
        change.setVariation(amount.toString());
        change.setVariationBefore(bdmUserVo.getEarnings().toString());
        change.setVariationAfter(bdmUserVo.getEarnings().add(amount).toString());
        change.setVariationType(3L);
        change.setAddOrSubtract(1L);
        change.setRelevantDocumentId(orderId);
        change.setBusinessType(BdmRoyaltyRecordEnum.getEnum(type).getDescription());
        iBdmBalanceChangeService.insertBdmBalanceChange(change);
    }

    /**
     * 修改用户收益
     *
     * @param userId   用户id
     * @param earnings 当前传入收益的值
     */
    private void updateBdmUser(Long userId, BigDecimal earnings, int flag) {
        // 查询用户信息
        BdmUserVo bdmUserVo = bdmUserMapper.getBdmUserByUserId(userId);
        // 计算收益信息(收益指的是不可用余额,确认收货后进行解冻)
        BdmUser bdmUser = new BdmUser();
        bdmUser.setSysUserid(bdmUserVo.getSysUserid());
        bdmUser.setId(bdmUserVo.getId());
        bdmUser.setEarnings(bdmUserVo.getEarnings().add(earnings));
//        if (flag == 1) {
//            bdmUser.setEarnings(bdmUserVo.getEarnings().add(earnings));
//        } else if (flag == 2) {
//            bdmUser.setRemainingSum(bdmUserVo.getRemainingSum().add(earnings));
//        }
        bdmUserMapper.updateBdmUser(bdmUser);
    }


    /**
     * 根据上级用户id修改级别
     * 购买者上级用户id
     *
     * @param upUserId
     */
    private void updateBdmMemberRule(Long upUserId, Long level) {
        bdmMemberRuleMapper.updateUpUserLevelByUpUserId(upUserId, level);
    }

    /**
     * 查询用户信息
     *
     * @param userId
     * @return
     */
    @Override
    public BdmUserVo getBdmUser(Long userId) {
        return bdmUserMapper.getBdmUserByUserId(userId);
    }

    /**
     * 根据上级id查询上级信息
     *
     * @param distributionParentId
     * @return
     */
    private BdmMemberRuleVo getMemberRule(Long distributionParentId) {
        return bdmMemberRuleMapper.selectMemberRuleByUserId(distributionParentId);
    }

    private void saveBdmMemberRule(Long userId, Long level, Long productId) {
        BdmMemberRule rule = new BdmMemberRule();
        rule.setSysUserid(userId);
        List<BdmMemberRule> bdmMemberRules = bdmMemberRuleMapper.selectBdmMemberRuleList(rule);
        if (CollectionUtils.isEmpty(bdmMemberRules)) {
            // 用户信息保持到用户会员表
            BdmMemberRule memberRule = new BdmMemberRule();
            memberRule.setMemberLevel(BdmMemberRuleEnum.VIP.getLevel());
            memberRule.setMemberName(BdmMemberRuleEnum.VIP.getDescription());
            estimateLevel(level, memberRule);
            memberRule.setSysUserid(userId);
            memberRule.setState(1L);
            memberRule.setCreateTime(new Date());
            memberRule.setGiftpackId(productId);
            bdmMemberRuleMapper.insertBdmMemberRule(memberRule);
        } else {
            if (level != 1){
                BdmMemberRule memberRule = bdmMemberRules.get(0);
                memberRule.setMemberAgencyLevel(level);
                memberRule.setUpdateTime(new Date());
                estimateLevel(level, memberRule);
                bdmMemberRuleMapper.updateBdmMemberRule(memberRule);
            }

        }

    }


    /**
     * 根据传入的会员等级类型返回对应会员等级信息
     *
     * @param memberLevelType
     * @return
     */
    private BdmMemberLevel getBdmMemberLevelByLevelType(List<BdmMemberLevel> levelList, Integer memberLevelType) {
        return levelList.stream().filter(f -> f.getMemberLevelType().equals(memberLevelType)).collect(Collectors.toList()).get(0);
    }


    private void extracted(String orderId, Long memberAgencyLevel, Long productLevel, List<BdmMemberLevel> levelList, BdmUserVo bdmUserVo,BdmGood bdmGood) {
        // 同等级平级推奖励
        if (memberAgencyLevel.equals(productLevel)) {
            // 总裁同级推
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.BOSS.getLevel())) {
                with(BdmMemberRuleEnum.BOSS.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.AGENCY_GRADE_AWARD.getType(), 1,bdmGood);
            }
            // 区域运营同级推
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.OPERATION.getLevel())) {
                with(BdmMemberRuleEnum.OPERATION.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.AGENCY_GRADE_AWARD.getType(), 1,bdmGood);
            }

            // 联创同级推
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.LAIN_CHANG.getLevel())) {
                with(BdmMemberRuleEnum.LAIN_CHANG.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.AGENCY_GRADE_AWARD.getType(), 1,bdmGood);
            }

            // 共享店主同级推
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.SHOPKEEPER.getLevel())) {
                with(BdmMemberRuleEnum.SHOPKEEPER.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.AGENCY_GRADE_AWARD.getType(), 1,bdmGood);
            }
        }
        // 直推奖励
        else if ((memberAgencyLevel - productLevel) >= 0) {
            // 总裁直推区域
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.BOSS.getLevel()) && memberAgencyLevel-productLevel==1) {
                with(BdmMemberRuleEnum.BOSS.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(), 2,bdmGood);
            }

            // 总裁直推联创
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.BOSS.getLevel()) && memberAgencyLevel-productLevel==2) {
                with(BdmMemberRuleEnum.BOSS.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(), 9,bdmGood);
            }

            // 总裁直推共享
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.BOSS.getLevel()) && memberAgencyLevel-productLevel==3) {
                with(BdmMemberRuleEnum.BOSS.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(), 10,bdmGood);
            }

            // 区域直推联创
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.OPERATION.getLevel())&&memberAgencyLevel - productLevel==1) {
                with(BdmMemberRuleEnum.OPERATION.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(), 2,bdmGood);
            }

            // 区域直推共享
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.OPERATION.getLevel())&&memberAgencyLevel - productLevel==2) {
                with(BdmMemberRuleEnum.OPERATION.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(), 11,bdmGood);
            }
            // 联创推共享店主
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.LAIN_CHANG.getLevel())) {
                with(BdmMemberRuleEnum.LAIN_CHANG.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType(), 2,bdmGood);
            }
        }
        // 跨级推奖励
        else {
            // 如果上级代理是共享等级
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.SHOPKEEPER.getLevel())) {
                // 共享店主推联创
                if ((memberAgencyLevel - productLevel) == -1) {
                    with(BdmMemberRuleEnum.SHOPKEEPER.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType(), 3,bdmGood);
                }
                // 共享店主推运营
                if ((memberAgencyLevel - productLevel) == -2) {
                    with(BdmMemberRuleEnum.SHOPKEEPER.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType(), 4,bdmGood);
                }

                // 共享店主推总裁
                if ((memberAgencyLevel - productLevel) == -3) {
                    with(BdmMemberRuleEnum.SHOPKEEPER.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType(), 5,bdmGood);
                }
            }
            // 如果上级代理是联创
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.LAIN_CHANG.getLevel())) {
                // 联创推运营
                if ((memberAgencyLevel - productLevel) == -1) {
                    with(BdmMemberRuleEnum.LAIN_CHANG.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType(), 6,bdmGood);
                }

                // 联创推总裁
                if ((memberAgencyLevel - productLevel) == -2) {
                    with(BdmMemberRuleEnum.LAIN_CHANG.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType(), 7,bdmGood);
                }
            }

            // 如果上级代理是运营
            if (memberAgencyLevel.equals(BdmMemberRuleEnum.OPERATION.getLevel())) {
                // 运营推总裁
                if ((memberAgencyLevel - productLevel) == -1) {
                    with(BdmMemberRuleEnum.OPERATION.getLevel(), levelList, bdmUserVo.getParentId(), orderId, BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType(), 8,bdmGood);
                }
            }
        }
    }

    private void extracted1(String orderId, Long memberAgencyLevel, Long productLevel, List<BdmMemberLevel> levelList, BdmUserVo bdmUserVo,BdmGood bdmGood) {
        String awardType = "";
        if (memberAgencyLevel.equals(productLevel)) {
            awardType = BdmRoyaltyRecordEnum.AGENCY_GRADE_AWARD.getType();
        }else if ((memberAgencyLevel - productLevel) >= 0) {
            awardType = BdmRoyaltyRecordEnum.DIRECT_PREMIUM.getType();
        }else{
            awardType =  BdmRoyaltyRecordEnum.SKIP_LEVEL_AWARD.getType();
        }

        BigDecimal zero = BigDecimal.ZERO;
        if(memberAgencyLevel.equals(BdmMemberRuleEnum.SHOPKEEPER.getLevel())){
            //共享店主
            zero=bdmGood.getDlbSharedShareBonus();
        }else if(memberAgencyLevel.equals(BdmMemberRuleEnum.LAIN_CHANG.getLevel())){
            // 联创
            zero=bdmGood.getDlbJointProductionBonus();
        }else if(memberAgencyLevel.equals(BdmMemberRuleEnum.OPERATION.getLevel())){
            //"区域运营"),
            zero=bdmGood.getDlbRegionalOperationBonus();
        }else if(memberAgencyLevel.equals(BdmMemberRuleEnum.BOSS.getLevel())){
              // 总裁
            zero=bdmGood.getDlbPresidentBonus();
        }
        insertBdmRoyaltyRecord( bdmUserVo.getParentId(), awardType, zero, orderId,2);
        // 修改上级收益
        this.updateBdmUser(bdmUserVo.getParentId(), zero,2);
    }


    /**
     * 代理层级
     *
     * @param memberLevelType      等级类型
     * @param levelList            等级集合
     * @param distributionParentId 上一级用户id
     * @param orderId              订单id
     * @param type                 分成类型
     * @param status               1同级 2直推 3共享推联创跨级奖 4共享推运营跨级奖 5共享推总裁跨级奖 6联创推运营 7联创推总裁 8区域运营推总裁奖
     */
    private void with(Long memberLevelType, List<BdmMemberLevel> levelList, Long distributionParentId, String orderId, String type, int status,BdmGood bdmGood) {
        BigDecimal zero = BigDecimal.ZERO;
        if (status == 1) {
            zero = zero.add(bdmGood.getAgencyGradeAward());
        } else if (status == 2) {
            zero = zero.add(bdmGood.getDirectPremium());
        } else if (status == 3) {
            zero = zero.add(bdmGood.getShareLianChangAward());
        } else if (status == 4) {
            zero = zero.add(bdmGood.getShareAreaAward());
        } else if (status == 5) {
            zero = zero.add(bdmGood.getShareBossAward());
        } else if (status == 6) {
            zero = zero.add(bdmGood.getLianChangAreaAward());
        } else if (status == 7) {
            zero = zero.add(bdmGood.getLianChangBossAward());
        } else if (status == 8) {
            zero = zero.add(bdmGood.getAreaBossAward());
        } else if (status == 9) {
            zero = zero.add(bdmGood.getBossLianChangAward());
        } else if (status == 10) {
            zero = zero.add(bdmGood.getBossShareAward());
        } else if (status == 11) {
            zero = zero.add(bdmGood.getAreaShareAward());
        }
        insertBdmRoyaltyRecord(distributionParentId, type, zero, orderId,2);
        // 修改上级收益
        this.updateBdmUser(distributionParentId, zero,2);
    }

    /**
     * 判断等级设置等级中文
     *
     * @param level
     * @param memberRule
     */
    private static void estimateLevel(Long level, BdmMemberRule memberRule) {
        if (level != 1) {
            memberRule.setMemberAgencyLevel(level);
            if (level.equals(BdmMemberRuleEnum.SHOPKEEPER.getLevel())) {
                memberRule.setMemberAgencyLevelName(BdmMemberRuleEnum.SHOPKEEPER.getDescription());
            }
            if (level.equals(BdmMemberRuleEnum.LAIN_CHANG.getLevel())) {
                memberRule.setMemberAgencyLevelName(BdmMemberRuleEnum.LAIN_CHANG.getDescription());
            }
            if (level.equals(BdmMemberRuleEnum.OPERATION.getLevel())) {
                memberRule.setMemberAgencyLevelName(BdmMemberRuleEnum.OPERATION.getDescription());
            }
            if (level.equals(BdmMemberRuleEnum.BOSS.getLevel())) {
                memberRule.setMemberAgencyLevelName(BdmMemberRuleEnum.BOSS.getDescription());
            }
        }
    }

    /**
     * 团队奖
     *
     * @param orderId
     * @param levelList
     * @param bdmGood
     * @param bdmUserVo
     */
    private void groupAward(String orderId, List<BdmMemberLevel> levelList,BdmGood bdmGood, BdmUserVo bdmUserVo,long directUserMemberLevel,int[] t1,BdmMemberRuleVo selfMemberRuleVo) {
        // 高推低或平推
        BdmMemberRuleVo memberRule = bdmMemberRuleMapper.selectMemberRuleByUserId(bdmUserVo.getSysUserid());
        if (memberRule != null) {
            BigDecimal zero = BigDecimal.ZERO;
            if((!ObjectUtils.isEmpty(memberRule.getMemberAgencyLevel())) && ((memberRule.getMemberAgencyLevel()>=directUserMemberLevel))
                    && ((memberRule.getMemberAgencyLevel()>selfMemberRuleVo.getMemberAgencyLevel()))){
              //  BdmMemberRuleEnum
                if (memberRule.getMemberAgencyLevel().equals(BdmMemberRuleEnum.SHOPKEEPER.getLevel()) ) {
                    if( t1[0]==0){
                        zero =  levelList.stream().filter(item ->item.getId()==3 ).collect(Collectors.toList()).get(0).getTeamAward();
                       // zero = zero.add(bdmGood.getLianchuangTeamAward());
                        t1[0]=1;
                    }
                }

                if (memberRule.getMemberAgencyLevel().equals(BdmMemberRuleEnum.LAIN_CHANG.getLevel()) ) {
                    if( t1[1]==0){
                        zero =  levelList.stream().filter(item ->item.getId()==4 ).collect(Collectors.toList()).get(0).getTeamAward();
                       // zero = zero.add(bdmGood.getLianchuangTeamAward());
                        t1[1]=1;
                    }

                }
                if (memberRule.getMemberAgencyLevel() .equals(BdmMemberRuleEnum.OPERATION.getLevel())) {
                    if( t1[2]==0){
                        zero =  levelList.stream().filter(item ->item.getId()==5 ).collect(Collectors.toList()).get(0).getTeamAward();
                       // zero = zero.add(bdmGood.getOperationTeamAward());
                        t1[2]=1;
                    }

                }
                if (memberRule.getMemberAgencyLevel()  .equals(BdmMemberRuleEnum.BOSS.getLevel())) {
                    if( t1[3]==0){
                        zero =  levelList.stream().filter(item ->item.getId()==15 ).collect(Collectors.toList()).get(0).getTeamAward();
                        //zero = zero.add(bdmGood.getBossTeamAward());
                        t1[3]=1;
                    }

                }
                if(zero.compareTo(BigDecimal.ZERO)!=0){
                    BigDecimal multiply = bdmGood.getRetailPrice().multiply(zero.divide(new BigDecimal(100),2, RoundingMode.HALF_UP));
                    multiply=multiply.setScale(2,RoundingMode.HALF_UP);
                    this.insertBdmRoyaltyRecord(bdmUserVo.getSysUserid(), BdmRoyaltyRecordEnum.GROUP_AWARD.getType(), multiply, orderId,2);
                    // 修改上级收益
                    this.updateBdmUser(bdmUserVo.getSysUserid(), multiply,2);
                }

            }
        }
    }

    /**
     * 获取所有代理等级,不包含vip的用户
     */
    private void getUpUser(List<BdmUserVo> voList, Long userId) {
        BdmUserVo bdmUser = this.getBdmUser(userId);
        if (bdmUser != null) {
            voList.add(bdmUser);
            if (bdmUser.getParentId() != null){
                getUpUser(voList,bdmUser.getParentId());
            }
        }
    }

   // 获取用户上级是 svip 的用户
    private void getSvipUpUser(Long userId,List<BdmUserVo>  svipList) {
        BdmUserVo bdmUser = this.getBdmUser(userId);
        if (bdmUser != null) {
            BdmMemberRule   directBdmMemberRule = bdmMemberRuleMapper.selectOne(Wrappers.<BdmMemberRule>lambdaQuery().eq(BdmMemberRule::getSysUserid,userId));
            if (directBdmMemberRule != null){
                if(directBdmMemberRule.getMemberLevel().equals(BdmMemberRuleEnum.SVIP.getLevel())){
                    svipList.add(bdmUser);
                    return;
                }else{
                    getSvipUpUser(bdmUser.getParentId(),svipList);
                }
            }
        }
    }



    /**
     * 上传订单信息到erp
     */
    @Override
    public BdmOrdersUploadDataDto logistics(List<BdmOrdersUploadDto> uploadDtos){
        // 实例化client
        ApiClient client = new DefaultApiClient();
        ApiRequest request = new ApiRequest.Builder(juShuiTanConfig.getOrdersUploadUrl(), juShuiTanConfig.getAppKey(), juShuiTanConfig.getAppSecret())
                .biz(JSON.toJSONString(uploadDtos)).build();

        // 执行接口调用
        ApiResponse response = client.execute(request, getJuShuiTanToken(true));
        JSONObject jsonObject = JSON.parseObject(response.getBody());
        if (jsonObject == null || !jsonObject.getString("code") .equals("0") || !jsonObject.getString("msg").equals("执行成功") || jsonObject.get("data") == null) {
            throw new RuntimeException("上传订单接口调用失败,失败原因:"+ response);
        }
        String jsonData = jsonObject.getString("data");
        String datas = JSON.parseObject(jsonData).getString("datas");

       return JSON.parseArray(datas, BdmOrdersUploadDataDto.class).get(0);

    }


    /**
     * 发货查询
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void shipmentsQuery() {
        List<BdmOrder> stayShipments = iBdmOrderService.lambdaQuery()
                .eq(BdmOrder::getOrderStatus, BdmOrderEnum.SHIPMENTS.getType())
                .list();

        if (CollectionUtils.isEmpty(stayShipments)) {
            return;
        }

        // ✅ 每批最多30个
        int batchSize = 30;
        int total = stayShipments.size();
        int batchCount = (total + batchSize - 1) / batchSize;

        log.info("待发货订单共 {} 条，分为 {} 批次处理", total, batchCount);

        for (int i = 0; i < total; i += batchSize) {
            List<BdmOrder> batchList = stayShipments.subList(i, Math.min(i + batchSize, total));
            handleBatchShipments(batchList);
        }
    }

    private void handleBatchShipments(List<BdmOrder> batchOrders) {
        if (CollectionUtils.isEmpty(batchOrders)) return;

        List<String> ids = batchOrders.stream().map(BdmOrder::getId).collect(Collectors.toList());

        HashMap<String, Object> map = new HashMap<>();
        map.put("shop_id", juShuiTanConfig.getShopId());
        map.put("so_ids", ids);

        // ✅ 调用聚水潭接口
        ApiClient client = new DefaultApiClient();
        ApiRequest request = new ApiRequest.Builder(
                juShuiTanConfig.getLogisticQueryUrl(),
                juShuiTanConfig.getAppKey(),
                juShuiTanConfig.getAppSecret()
        ).biz(JSON.toJSONString(map)).build();

        ApiResponse response = client.execute(request, getJuShuiTanToken(true));
        String body = response.getBody();
        JSONObject jsonObject = JSON.parseObject(body);

        if (jsonObject == null
                || !"0".equals(jsonObject.getString("code"))
                || !"执行成功".equalsIgnoreCase(jsonObject.getString("msg"))) {
            throw new RuntimeException("调用聚水潭发货查询失败, 批次订单: " + ids + " 原因: " + body);
        }

        String data = jsonObject.getString("data");
        String orders = JSON.parseObject(data).getString("orders");
        List<BdmOrderVo> bdmOrderVos = JSON.parseArray(orders, BdmOrderVo.class);

        if (CollectionUtils.isEmpty(bdmOrderVos)) {
            log.warn("批次订单 {} 未返回发货数据", ids);
            return;
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (BdmOrderVo orderVo : bdmOrderVos) {
            BdmOrder order = iBdmOrderService.lambdaQuery()
                    .eq(BdmOrder::getOId, orderVo.getO_id())
                    .eq(BdmOrder::getId, orderVo.getSo_id())
                    .one();

            if (order == null) continue;

            order.setLogisticsCompany(orderVo.getLogistics_company());
            order.setLId(orderVo.getL_id());
            order.setLcId(orderVo.getLc_id());
            order.setOrderStatus(BdmOrderEnum.DISTRIBUTION.getType());

            try {
                order.setSendTime(dateFormat.parse(orderVo.getSend_date()));
            } catch (ParseException e) {
                throw new RuntimeException("日期格式错误：" + orderVo.getSend_date());
            }

            // ✅ 更新订单状态
            iBdmOrderService.updateById(order);

            // ✅ 记录发货日志
            BdmOrderShipments bdmOrderShipment = new BdmOrderShipments();
            bdmOrderShipment.setUserName(order.getUserName());
            bdmOrderShipment.setCreateTime(DateUtils.getNowDate());
            bdmOrderShipment.setUserId(order.getUserId());
            bdmOrderShipment.setSoId(order.getId());
            bdmOrderShipment.setOrderStatus(BdmOrderEnum.GATHER.getType());
            bdmOrderShipment.setParticulars("手机号为：" + order.getPhoneNumber() + " 用户订单已发货");
            bdmOrderShipmentsService.save(bdmOrderShipment);

            // ✅ 同步微信物流
            try {
                String appId = WxConfig.APP_ID;
                String secret = WxConfig.secret;
                String accessToken = getAccessToken(appId, secret);
                String mchId = "798633418";

                BdmUserVo bdmUserVo = bdmUserMapper.selectUserByUserId(order.getUserId());
                uploadShippingInfo(mchId, order.getNativeId(), accessToken,
                        bdmUserVo.getOpenId(), order.getGoodNames(),
                        order.getLcId(), order.getLId());
            } catch (Exception e) {
                log.error("微信物流同步失败：订单{}，错误{}", order.getId(), e.getMessage());
            }
        }
    }


    /**
     * 向微信上传订单物流信息
     *
     * @param mchId          商户号（微信支付分配）
     * @param outTradeNo     商户订单号 或 微信支付订单号（取决于 order_number_type）
     * @param accessToken    小程序调用凭证（注意要定时刷新）
     * @param openid         用户的 openid（付款用户）
     * @param desc           商品描述（例如：苹果手机一台）
     * @param expressCompany 快递公司编码（如：SF 表示顺丰）
     * @param trackingNo     快递单号
     */
    public void uploadShippingInfo(String mchId,
                                   String outTradeNo,
                                   String accessToken,
                                   String openid,
                                   String desc,
                                   String expressCompany,
                                   String trackingNo) {

        // 1. 构建请求地址（access_token 必须是小程序的，且有效）
        RestTemplate restTemplate = new RestTemplate();
        String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken;

        // 2. 设置请求头：Content-Type 为 application/json
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);

        // 3. 构建订单标识对象（order_key）
        JSONObject orderKey = new JSONObject();
        // 订单单号类型：1=商户单号（out_trade_no），2=微信支付订单号（transaction_id）
        orderKey.put("order_number_type", 2);
        orderKey.put("mchid", mchId);
        // 如果使用 transaction_id，则这里传微信支付单号
        orderKey.put("transaction_id", outTradeNo);
        // 如果使用商户单号模式：
        // orderKey.put("out_trade_no", outTradeNo);

        // 4. 构建单个商品的物流信息
        JSONObject shippingList = new JSONObject();
        shippingList.put("item_desc", desc);           // 商品描述
        shippingList.put("tracking_no", trackingNo);   // 物流单号
        shippingList.put("express_company", expressCompany); // 快递公司编码

        // 5. 构建付款人信息
        JSONObject payer = new JSONObject();
        payer.put("openid", openid);

        // 6. 组装请求参数
        JSONObject signObject = new JSONObject();
        JSONArray shipping_list = new JSONArray();
        shipping_list.add(shippingList);

        // 上传时间（必须是 ISO8601 格式，例如：2025-08-29T09:00:00+0800）
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        String uploadTime = simpleDateFormat.format(System.currentTimeMillis());

        signObject.put("order_key", orderKey); // 订单标识
        signObject.put("delivery_mode", 1);    // 发货模式：1=统一发货，2=分拆发货
        signObject.put("logistics_type", 1);   // 物流方式：1=快递，2=同城配送，3=虚拟商品，4=自提
        signObject.put("shipping_list", shipping_list); // 物流明细
        signObject.put("upload_time", uploadTime);      // 上传时间
        signObject.put("payer", payer);                 // 用户信息

        // 7. 构建请求体
        HttpEntity<JSONObject> requestEntity = new HttpEntity<>(signObject, headers);

        // 8. 调用微信 API
        ResponseEntity<String> responseEntity =
                restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);

        // 9. 打印返回结果（可根据 errcode 判断是否成功）
        String body = responseEntity.getBody();
        System.out.println("微信返回结果：" + body);
        System.out.println("上传物流信息完成");

        // 10. 建议在这里解析返回结果：
        // JSONObject jsonObject = JSONUtil.parseObj(body);
        // String errcode = jsonObject.getString("errcode");
        // if (!"0".equals(errcode)) { ... } // 处理异常情况
    }

    public String getAccessToken(String appid, String secret) {
        // log.info("initAccessToken:开始运行...");
        String accessToken = null;
        //获取tokcen接口
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.parseObject(message);
            accessToken = demoJson.getString("access_token");

            //log.info("返回accessToken:"+accessToken);
            //log.info("initAccessToken:运行结束...");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return accessToken;

    }

    /**
     * 获取订单物流轨迹
     * shipperCode 快递编码
     * logisticCode 快递单号
     * sort 1降序
     * @param map
     * @return
     */
    @Override
    public List<BdmOrderPhysicalDistributionVo> getOrderPhysicalDistribution(Map<String, String> map) {
        try {
            String request = remoteRequest(JSON.toJSONString(map));
            String traces = JSON.parseObject(request).getString("Traces");
            return JSON.parseArray(traces, BdmOrderPhysicalDistributionVo.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("调用查询物流信息接口失败");
        }
    }

    /**
     * 取消订单
     */
    @Override
    public void cancelOrder(List<String> ids){
        HashMap<String, Object> map = new HashMap<>();
        map.put("cancel_type","不想要了");
        map.put("o_ids",ids);

        // 实例化client
        ApiClient client = new DefaultApiClient();
        ApiRequest request = new ApiRequest.Builder(juShuiTanConfig.getCancelOrderUrl(), juShuiTanConfig.getAppKey(), juShuiTanConfig.getAppSecret())
                .biz(JSON.toJSONString(map)).build();

        // 执行接口调用
        ApiResponse response = client.execute(request, getJuShuiTanToken(true));
        String body = response.getBody();
        JSONObject jsonObject = JSON.parseObject(body);
        log.info(jsonObject.toJSONString());
        if (jsonObject.isEmpty() || !jsonObject.getString("code") .equals("0") || !jsonObject.getString("msg") .equalsIgnoreCase("执行成功")) {
            throw new RuntimeException("取消订单失败,失败原因是:"+body);
        }
    }

    /**
     * 获取聚水潭授权token
     */
    public String getJuShuiTanToken(boolean flag){
        HashMap<String, String> map = new HashMap<>();
        map.put("app_key", juShuiTanConfig.getAppKey());
        map.put("timestamp", System.currentTimeMillis() / 1000 + "");
        map.put("grant_type", "refresh_token");
        map.put("charset", "utf-8");
        map.put("code", UUID.randomUUID().toString().replace("-","").substring(0, 6));
        String sign = SignUtil.getSign(juShuiTanConfig.getAppSecret(), map);
        map.put("sign", sign);
        ////////////
        System.out.println(map.toString());
        String dataJson = sendPost(juShuiTanConfig.getJushuitanTokenUrl(), map);
        log.info(dataJson);
        JSONObject data = JSONObject.parseObject(dataJson);
        if (data == null || !data.getString("code").equalsIgnoreCase("0")) {
            throw new RuntimeException("获取聚水潭授权token失败");
        }
        String token;
        if (flag){
            token = JSONObject.parseObject(data.getString("data")).getString("access_token");
        }else {
            token = JSONObject.parseObject(data.getString("data")).getString("refresh_token");
        }
        return token;
    }

    /**
     * 刷新授权access_token
     */
    @Override
    public void refreshToken(){
        HashMap<String, String> map = new HashMap<>();
        map.put("app_key", juShuiTanConfig.getAppKey());
        map.put("timestamp", System.currentTimeMillis() / 1000 + "");
        map.put("grant_type", "refresh_token");
        map.put("charset", "utf-8");
        map.put("refresh_token", getJuShuiTanToken(false));
        map.put("scope", "all");
        String sign = SignUtil.getSign(juShuiTanConfig.getAppSecret(), map);
        map.put("sign", sign);

        String dataJson = sendPost(juShuiTanConfig.getUpdateAccessTokenUrl(), map);
        JSONObject data = JSONObject.parseObject(dataJson);
        if (data == null || !data.getString("code").equalsIgnoreCase("0")) {
            throw new RuntimeException("聚水潭授权token刷新失败");
        }
        log.info("更新token接口返回的数据是:{}",dataJson);
    }

    /**
     * 第三方 退款
     * @param amount
     */
    @Override
    public JSONObject polymerizationPay(String amount, String transactionId) {
        HashMap<String, String> map = new HashMap<>();
        // 终端授权码
        map.put("terminalCode", WxPayConfig.APIKEY);
        // 金额
        map.put("amount", amount);
        // 订单号
        map.put("outTradeNo", transactionId);
        String url = "https://www.yqdfpay.com/api/third/v2.0/refund";
        // 随机字符串
        map.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));
        try {
            // 终端授权密码
            String generateSign = generateSign(map, WxPayConfig.PRIVATE_KEY);
            String sign = MD5(generateSign, charset);
            map.put("sign", sign);
            RestTemplate restTemplate = createRestTemplateWithoutSSL();
            ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, map, String.class);
            JSONObject jsonObject = JSONObject.parseObject(stringResponseEntity.getBody());
            return jsonObject;
        } catch (Exception e) {
            throw new RuntimeException("退款失败");
        }
    }




    public static RestTemplate createRestTemplateWithoutSSL() throws Exception {
        // 创建信任所有证书的 SSL 上下文
        SSLContext sslContext = new SSLContextBuilder()
                .loadTrustMaterial(null, (certificate, authType) -> true)
                .build();

        // 配置 SSL 工厂和 Hostname 验证器
        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                sslContext,
                NoopHostnameVerifier.INSTANCE);

        // 创建 HttpClient
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(socketFactory)
                .build();

        // 使用自定义的 HttpClient 创建 RestTemplate
        HttpComponentsClientHttpRequestFactory factory =
                new HttpComponentsClientHttpRequestFactory(httpClient);

        return new RestTemplate(factory);
    }


    /**
     * 远程请求
     *
     * @param requestData   应用级参数
     * @return java.lang.String
     * @author kdniao
     * @date 2024/12/20 17:14
     **/
    private static String remoteRequest(String requestData) throws Exception {
        // 组装系统级参数
        Map<String, String> params = new HashMap<>(4);
        params.put("EBusinessID", EBusinessID);
        params.put("RequestType", "8001");
        params.put("RequestData", requestData);
        params.put("DataType", "2");
        String dataSign = encrypt(requestData, appKey, charset);
        params.put("DataSign", urlEncoder(dataSign));
        // 以form表单形式提交post请求，post请求体中包含了应用级参数和系统级参数
        String s = sendPost(sandRequestUrl, params);
        return s;
    }
    /**
     * MD5加密
     * str 内容
     * charset 编码方式
     *
     * @throws Exception
     */
    private static String MD5(String str, String charset) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(charset));
        byte[] result = md.digest();
        StringBuilder sb = new StringBuilder(32);
        for (byte b : result) {
            int val = b & 0xff;
            if (val <= 0xf) {
                sb.append("0");
            }
            sb.append(Integer.toHexString(val));
        }
        return sb.toString().toLowerCase();
    }
    /**
     * base64编码
     * str 内容
     * charset 编码方式
     *
     * @throws UnsupportedEncodingException
     */
    private static String base64(String str, String charset) throws UnsupportedEncodingException {
        return Base64.encode(str.getBytes(charset));
    }

    private static String urlEncoder(String str) throws UnsupportedEncodingException {
        return URLEncoder.encode(str, charset);
    }
    /**
     * Sign签名生成
     * <p>
     * 1、数据内容签名，加密方法为：把(请求内容(未编码)+ApiKey)进行MD5加密--32位小写，然后Base64编码，最后进行URL(utf-8)编码
     * <p>
     *
     * @param content  内容
     * @param keyValue ApiKey
     * @param charset  编码方式
     * @return java.lang.String dataSign签名
     * @author kdniao
     * @date 2024/12/20 15:25
     **/
    private static String encrypt(String content, String keyValue, String charset) throws Exception {
        if (keyValue != null) {
            return base64(MD5(content + keyValue, charset), charset);
        }
        return base64(MD5(content, charset), charset);
    }
    /**
     * 向指定 URL 发送POST方法的请求
     * url 发送请求的 URL
     * params 请求的参数集合
     *
     * @return 远程资源的响应结果
     */
    private static String sendPost(String url, Map<String, String> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // POST方法
            conn.setRequestMethod("POST");
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), charset);
            // 发送请求参数
            if (params != null) {
                StringBuilder param = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if (param.length() > 0) {
                        param.append("&");
                    }
                    param.append(entry.getKey());
                    param.append("=");
                    param.append(entry.getValue());
                    System.out.println(entry.getKey() + ":" + entry.getValue());
                }
                System.out.println("param:" + param.toString());
                out.write(param.toString());
            }
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), charset));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

    public static String generateSign(Map<String, String> params, String password) {
        // 1. 过滤并排序参数
        TreeMap<String, String> sortedParams = new TreeMap<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();

            // 跳过sign字段和空值
            if ("sign".equalsIgnoreCase(key) || value == null || value.isEmpty()) {
                continue;
            }
            sortedParams.put(key, value);
        }

        // 2. 拼接字符串
        StringBuilder signString = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            if (signString.length() > 0) {
                signString.append("&");
            }
            signString.append(entry.getKey()).append("=").append(entry.getValue());
        }
        // 3. 拼接支付密码（关键补充）
        signString.append("&key=").append(password);
        return signString.toString();
    }
}
